package br.usp.ime.dojo.client;


import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class DojoRoomCreator extends Composite {

	private TextBox roomNameTB;
	private TextBox descriptionTB;
	private String creatorName;
	private Button createRoomBTN;
	private Label roomNameLBL;
	private Label descriptionLBL;
	private VerticalPanel createBox;
	private VerticalPanel panel;
	private DojoRoomDTO createdRoom;
	private DojoRoomServiceAsync dojoRoomSvc;
	private Label nameErrorLBL;
	private Label descriptionErrorLBL;
	private JoinARoomListener joinARoomListener;
	private List<CheckBox> languagesList;
	private VerticalPanel languagesPNL;
	
	public DojoRoomCreator(String creatorName){
		this();
		this.setCreatorName(creatorName);
	}
	
	public DojoRoomCreator() {
		dojoRoomSvc = GWT.create(DojoRoomService.class);
		roomNameLBL = new Label("Room name:");
		roomNameTB = new TextBox();
		
		descriptionLBL = new Label("Room description:");
		descriptionTB = new TextBox();
		
		createRoomBTN = new Button("Create!");
		createRoomBTN.addClickListener(new ClickListener(){

			public void onClick(Widget sender) {
				createDojoRoom();
			}			
		});
		
		roomNameTB.addKeyboardListener(new KeyboardListenerAdapter(){
			@Override
			public void onKeyDown(Widget sender, char keyCode, int modifiers) {
				if(keyCode == KEY_ENTER) {
					createDojoRoom();
				}
			}			
		});
		
		panel = new VerticalPanel();
		
		createBox = new VerticalPanel();
		createBox.setStylePrimaryName("dojoBox");
		createBox.addStyleDependentName("createBox");
		buildLanguagesList();
		
		initWidget(panel);
	}
	
	private List<String> getSelectedLanguages() {
		List<String> selectedLanguages = new ArrayList<String>();
		for (CheckBox cb : languagesList) {
			if (cb.isChecked()) {
				selectedLanguages.add(cb.getText());
			}
		}
		return selectedLanguages;
	}
	
	private void buildLanguagesList() {
		languagesPNL = new VerticalPanel();
		
		if (dojoRoomSvc == null) {
			dojoRoomSvc = GWT.create(DojoRoomService.class);

		}
		AsyncCallback<List<String>> callback = new AsyncCallback<List<String>>() {

			public void onFailure(Throwable caught) {
				setNameError(caught.getMessage());
			}

			public void onSuccess(List<String> languages) {
				languagesList = new ArrayList<CheckBox>();
				for (String language : languages) {
					languagesList.add(new CheckBox(language));
				}
				for (CheckBox cb : languagesList) {
					languagesPNL.add(cb);
				}
				createBox.add(roomNameLBL);
				createBox.add(roomNameTB);
				createBox.add(descriptionLBL);
				createBox.add(descriptionTB);
				createBox.add(languagesPNL);
				createBox.add(createRoomBTN);
				
				panel.add(createBox);
			}
			
			
		};
		dojoRoomSvc.getAvailableLanguages(callback);
	}
	
	private void createDojoRoom() {
		
		if (nameErrorLBL != null){
			nameErrorLBL.removeFromParent();
			nameErrorLBL = null;
		}
		if (descriptionErrorLBL != null){
			descriptionErrorLBL.removeFromParent();
			descriptionErrorLBL = null;
		}
		
		String roomName = roomNameTB.getText();
		if (roomName.isEmpty())
			setNameError("Room name must not be empty.");
		else if (roomName.trim().isEmpty())	
			setNameError("Room name must not contain only whitespaces.");

		String description = descriptionTB.getText();
		if (description.isEmpty())
			setDescriptionError("Description must not be empty.");
		else if (description.trim().isEmpty())
			setDescriptionError("Description must not contain only whitespaces.");


		if(nameErrorLBL == null && descriptionErrorLBL == null) {
			AsyncCallback<DojoRoomDTO> callback = new AsyncCallback<DojoRoomDTO>() {

				public void onFailure(Throwable caught) {
					setNameError(caught.getMessage());
				}

				public void onSuccess(DojoRoomDTO result) {
					createdRoom = result;
					joinARoomListener.onJoinRequest(createdRoom);		
				}
				
				
			};
			// Make the call to the identification service.
			dojoRoomSvc.createDojoRoom(roomNameTB.getText(), descriptionTB.getText(), this.getCreatorName(), getSelectedLanguages(), callback);
		}
	}

	private void setNameError(String string) {
		nameErrorLBL = new Label(string);
		nameErrorLBL.setStylePrimaryName("dojoError");
		createBox.insert(nameErrorLBL, createBox.getWidgetIndex(roomNameTB));
	}
	
	private void setDescriptionError(String string) {
		descriptionErrorLBL = new Label(string);
		descriptionErrorLBL.setStylePrimaryName("dojoError");
		createBox.insert(descriptionErrorLBL, createBox.getWidgetIndex(descriptionTB));
	}

	public DojoRoomDTO getCreatedRoom() {
		return createdRoom;
	}

	public void setJoinRequestListener(JoinARoomListener dojoOnline) {
		joinARoomListener = dojoOnline;		
	}

	public void setCreatorName(String creatorName) {
		this.creatorName = creatorName;
	}

	public String getCreatorName() {
		return creatorName;
	}
	
}
